﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ImgCore;
using ImgCore.Sprite;

namespace ImgTool
{
    public partial class ImgTool : Form
    {

        protected Img currentImg;
        protected Dictionary<string, Img> ImgList;

        public ImgTool()
        {
            InitializeComponent();
        }

        private void ImgTool_Load(object sender, EventArgs e)
        {
            splitType.SelectedIndex = 0;
            currentImg = null;
            ImgList = new Dictionary<string, Img>();
        }

        #region 切分

        private void textSource_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
            }
            else
            {
                e.Effect = DragDropEffects.None; 
            }
        }

        private void textSource_DragDrop(object sender, DragEventArgs e)
        {
            string fileSource = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();

            try
            {
                this.currentImg = new Img(fileSource);
                pictureSource.BackgroundImage = null;
                textSource.Text = fileSource;
                lbWidth.Text = this.currentImg.Width.ToString();
                lbHeight.Text = this.currentImg.Height.ToString();
                pictureSource.Load(fileSource);
            }
            catch (Exception)
            {
                MessageBox.Show(string.Format("无法加载文件{0}", fileSource), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);                
            }

        }

        private void textSource_DoubleClick(object sender, EventArgs e)
        {
            pictureSource.Image = null;
            pictureSource.BackgroundImage = global::ImgTool.Properties.Resources.Split_Default_SourceBackground;
            textSource.Text = "";
            lbWidth.Text = "";
            lbHeight.Text = "";
        }

        private void btnSplit_Click(object sender, EventArgs e)
        {
            if (textSource.Text == "")
            {
                MessageBox.Show("请先选择要切分的图片文件！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (!(numX.Value >= 1 && this.currentImg.Width >= numX.Value))
            {
                MessageBox.Show(string.Format("X取值{0}非法！", numX.Value), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (!(numY.Value >= 1 && this.currentImg.Height >= numY.Value))
            {
                MessageBox.Show(string.Format("Y取值{0}非法！", numY.Value), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (splitType.SelectedIndex == 1 && this.currentImg.Width % numX.Value != 0)
            {
                MessageBox.Show(string.Format("在X轴方向切分的数量{0}不是原图宽度{1}的约数！", numX.Value, this.currentImg.Width), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (splitType.SelectedIndex == 1 && this.currentImg.Height % numY.Value != 0)
            {
                MessageBox.Show(string.Format("在Y轴方向切分的数量{0}不是原图高度{1}的约数！", numY.Value, this.currentImg.Height), "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                btnSplit.Enabled = false;
                int unitW, unitH;

                if (splitType.SelectedIndex == 1)
                {
                    //按数量
                    unitW = Convert.ToInt32(this.currentImg.Width / numX.Value);
                    unitH = Convert.ToInt32(this.currentImg.Height / numY.Value);
                }
                else
                {
                    //按像素
                    unitW = Convert.ToInt32(numX.Value);
                    unitH = Convert.ToInt32(numY.Value);
                }

                this.currentImg.Split(unitW, unitH);
                MessageBox.Show("图片切分成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("切分图片时发生异常：[{0}] {1}！", ex.GetType().ToString(), ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                btnSplit.Enabled = true;
            }
        }

        #endregion

        #region 合并

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (selectFileDlg.ShowDialog() == DialogResult.OK)
            {
                foreach (string filename in selectFileDlg.FileNames)
                {
                    AddToList(filename);
                }
            }
        }

        private void AddToList(string filename)
        {
            if (!fileList.Items.Contains(filename) && !ImgList.Keys.Contains(filename))
            {
                try
                {
                    ImgList.Add(filename, new Img(filename));
                }
                catch (Exception)
                {
                    MessageBox.Show(string.Format("无法加载文件{0}", filename), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                if (ImgList.Keys.Contains(filename))
                {
                    fileList.Items.Add(filename);
                }
            }
        }

        private void fileList_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void fileList_DragDrop(object sender, DragEventArgs e)
        {
            foreach (string filename in (System.Array)e.Data.GetData(DataFormats.FileDrop))
            {
                AddToList(filename);
            }
        }

        private void SetEnable(bool enable)
        {
            fileList.AllowDrop = enable;

            btnAdd.Enabled = enable;
            btnClear.Enabled = enable;            
            btnRemove.Enabled = enable;
            btnUp.Enabled = enable;
            btnDown.Enabled = enable;

            btnSaveHeight.Enabled = enable;
            btnSaveFree.Enabled = enable;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            SetEnable(false);
            try
            {
                ImgList.Clear();
                fileList.Items.Clear();
                GC.Collect();
            }
            catch (Exception)
            {
            }
            SetEnable(true);
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            SetEnable(false);
            if (fileList.SelectedItems.Count > 0)
            {
                string filename = (string)fileList.Items[fileList.SelectedIndex]; ;
                if (ImgList.Keys.Contains(filename))
                {
                    ImgList.Remove(filename);
                }
                fileList.Items.RemoveAt(fileList.SelectedIndex);
            }
            SetEnable(true);
        }

        private void btnUp_Click(object sender, EventArgs e)
        {
            SetEnable(false);
            if (fileList.SelectedItems.Count > 0)
            {
                object selected = fileList.SelectedItem;
                int indx = fileList.Items.IndexOf(selected);
                int totl = fileList.Items.Count;

                if (indx == 0)
                {
                    fileList.Items.Remove(selected);
                    fileList.Items.Insert(totl - 1, selected);
                    fileList.SetSelected(totl - 1, true);
                }
                else
                {
                    fileList.Items.Remove(selected);
                    fileList.Items.Insert(indx - 1, selected);
                    fileList.SetSelected(indx - 1, true);
                }
            }
            SetEnable(true);
        }

        private void btnDown_Click(object sender, EventArgs e)
        {
            SetEnable(false);
            if (fileList.SelectedItems.Count > 0)
            {
                object selected = fileList.SelectedItem;
                int indx = fileList.Items.IndexOf(selected);
                int totl = fileList.Items.Count;

                if (indx == totl - 1)
                {
                    fileList.Items.Remove(selected);
                    fileList.Items.Insert(0, selected);
                    fileList.SetSelected(0, true);
                }
                else
                {
                    fileList.Items.Remove(selected);
                    fileList.Items.Insert(indx + 1, selected);
                    fileList.SetSelected(indx + 1, true);
                }
            }
            SetEnable(true);
        }

        private void btnSaveHeight_Click(object sender, EventArgs e)
        {
            SetEnable(false);
            if (fileList.Items.Count > 0)
            {
                Size size;
                if (CheckAndCalc_Height(out size))
                {
                    string path = null;
                    if (GetSavedPath(out path))
                    {
                        using (Image newImage = new Bitmap(size.Width, size.Height))
                        {
                            using (Graphics newG = Graphics.FromImage(newImage))
                            {
                                int currentRow = 0;
                                int currentWidth = 0;
                                int unitHeight = ImgList.First().Value.Height;

                                for (int i = 0; i < fileList.Items.Count; i++)
                                {
                                    string item = (string)fileList.Items[i];
                                    Point location = new Point(
                                        currentWidth + 1,
                                        currentRow * unitHeight + 1);
                                    ImgList[item].DrawTo(newG, location);
                                    currentWidth += ImgList[item].Width;

                                    if ((i + 1) % numCount.Value == 0)
                                    {
                                        currentRow += 1;
                                        currentWidth = 0;
                                    }
                                }

                                Img newImg = new Img(newImage);
                                newImg.SetPath(path);
                                newImg.Save();
                            }
                        }
                        MessageBox.Show("图片合并成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }                
            }
            else
            {
                MessageBox.Show("请先选择要合并的图片文件！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            SetEnable(true);
        }

        private bool CheckAndCalc_Height(out Size rect)
        {
            int unitHeight = ImgList.First().Value.Height;
            int maxWidth = 0;
            int currentWidth = 0;
            for (int i = 0; i < fileList.Items.Count; i++)
            {
                string item = (string)fileList.Items[i];
                if (unitHeight == ImgList[item].Height)
                {
                    currentWidth += ImgList[item].Width;
                    if ((i + 1) % numCount.Value == 0 || i + 1 == fileList.Items.Count)
                    {
                        maxWidth = currentWidth > maxWidth ? currentWidth : maxWidth;
                        currentWidth = 0;
                    }                    
                }
                else
                {
                    fileList.SelectedIndex = i;
                    MessageBox.Show(string.Format("图片{0}的高度{1}与第一个图片的高度{2}不同，请核对所选图片高度后重试！", item, ImgList[item].Height, unitHeight), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    rect = new Size();
                    return false;
                }
            }
            int rowCount = fileList.Items.Count % Convert.ToInt32(numCount.Value);
            if (rowCount == 0)
            {
                rowCount = fileList.Items.Count / Convert.ToInt32(numCount.Value);
            }
            else
            {
                rowCount = Convert.ToInt32(Math.Floor(fileList.Items.Count / numCount.Value)) + 1;
            }
            rect = new Size(maxWidth, unitHeight * rowCount);
            return true;
        }

        private void btnSaveFree_Click(object sender, EventArgs e)
        {
            SetEnable(false);
            if (fileList.Items.Count > 0)
            {
                string path = null;
                if (GetSavedPath(out path))
                {
                    SpriteInfo input = new SpriteInfo();
                    input.inputFiles = new Dictionary<int, InputFile>();
                    input.distanceBetweenImages = Convert.ToInt32(numDistance.Value);

                    for (int i = 0; i < fileList.Items.Count; i++)
                    {
                        input.inputFiles.Add(i, new InputFile(fileList.Items[i].ToString(), ImgList[fileList.Items[i].ToString()]));
                    }              

                    input.outputSpriteFilePath = path;
                    input.outputCssFilePath = System.IO.Path.Combine(
                        System.IO.Path.GetDirectoryName(path),
                        string.Format("{0}.{1}", System.IO.Path.GetFileNameWithoutExtension(path), "css"));
                    
                    Sprite sprite = new Sprite(input);
                    sprite.Create();

                    MessageBox.Show("图片合并成功！同名CSS文件已经生成！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("请先选择要合并的图片文件！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            SetEnable(true);
        }

        private bool GetSavedPath(out string path)
        {
            path = null;
            if (saveFileDlg.ShowDialog() == DialogResult.OK)
            {
                path = saveFileDlg.FileName;
                return true;
            }
            return false;
        }

        #endregion

        #region 关于
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.techotaku.net");
        }

        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://weibo.com/tarot13");
        }

        private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://github.com/techotaku");
        }

        private void linkLabel4_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.microsoft.com/en-us/openness/licenses.aspx#MPL");
        }

        private void linkLabel5_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://github.com/ricmrodrigues");
        }
        #endregion

    }
}
